import inspect
import os
import sys
import time
import static.globals as sg
import requests
from selenium.common import TimeoutException

from cache.redis_util import getConnection
from sel.proxy.selenium_proxy_auth_plugin import create_proxy_auth_extension as cpae
from selenium.webdriver import ChromeOptions
import undetected_chromedriver as uc
from seleniumwire import undetected_chromedriver as uc_wire

def tab2Page(browser,handles,tabIndex,pageHost):
    browser.switch_to.window(handles[tabIndex])
    browser.get(pageHost)

def getProxyOptions(host,port,username , password):
    # username = 'd2716458517'
    # password = 'ela9v3e9'
    proxy_options = {
        'proxy': {
            'http': f'http://{username}:{password}@{host}:{port}',
            'https': f'https://{username}:{password}@{host}:{port}',
            'no_proxy': 'localhost,127.0.0.1',
            'verify_ssl': False
        }
    }
    return proxy_options


def initSelWireChrome(useProxy,isHeadless,host,setTimeOut,ignorePic,redis):
    options = uc.ChromeOptions()
    options.add_argument("--disable-blink-features=AutomationControlled")
    driver_path = r'C:\Program Files\Google\Chrome\Application\chromedriver.exe'
    options.add_argument('--ignore-certificate-errors')
    options.add_argument('--ignore-ssl-errors')
    options.add_argument('--allow-insecure-localhost')
    if(ignorePic):      # 放弃加载图片等 来加速加载
        prefs = {
            'profile.default_content_setting_values': {
                'images': 2,  # 2表示禁止加载图片
                # 其他设置选项：
                'javascript': 1,  # 1允许，2禁止
                'plugins': 2,     # 禁止插件
                'popups': 2,      # 禁止弹窗
                'geolocation': 2, # 禁止地理位置
                'notifications': 2, # 禁止通知
                'auto_select_certificate': 2,
                'fullscreen': 2,
                'mouselock': 2,
                'mixed_script': 2,
                'media_stream': 2,
            }
        }
        options.add_experimental_option('prefs', prefs)
    if isHeadless:
        #  普通chorme的无头配置
        # options.add_argument('--headless')
        # options.add_argument('--no-sandbox')
        # options.add_argument('--disable-dev-shm-usage')
        # options.add_argument('--disable-gpu')
        # options.add_argument('--window-size=1920,1080')

        # uc_wire。chrome 的专用无头模式配置
        options.add_argument('--headless=new')
        options.add_argument('--no-sandbox')
        options.add_argument('--disable-dev-shm-usage')
        options.add_argument('--disable-gpu')

        # uc_wire 专用配置
        options.add_argument('--disable-blink-features=AutomationControlled')
        options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36')
    if useProxy:
        if(redis == None):              # 正常从
            proxy_data = get_proxy()
            proxy_host = proxy_data.get('proxy_address').split(":")[0]            # proxy ip
            proxy_port = proxy_data.get('proxy_address').split(":")[1]            # proxy port
            proxy_options = getProxyOptions(proxy_host,proxy_port,proxy_data.get('proxy_uname'),proxy_data.get('proxy_pass'))
        else:
            # 先从缓存中拿proxy
            name = f'stock:proxy:ex:{sg.batch}'
            if redis.exists(name):
                print("=============get proxy from redis=============")
                proxy_host = redis.hget(name=name,key='proxy_host').decode('utf-8')
                proxy_port = redis.hget(name=name,key='proxy_port').decode('utf-8')
                proxy_uname = redis.hget(name=name,key='proxy_uname').decode('utf-8')
                proxy_pass = redis.hget(name=name,key='proxy_pass').decode('utf-8')
                proxy_options = getProxyOptions(proxy_host,proxy_port,proxy_uname,proxy_pass)
                proxy_data = {'proxy_address':f'{proxy_host}:{proxy_port}'}
                print()
            else:
                print("=============get proxy from api=============")

                # 判断代理令牌是否已用完, 额度用完了就不走get_proxy
                tokenCount = redis.incr("stock:count:gn:token")
                if tokenCount > 150:
                    sg.tokenOut = True
                    return None

                proxy_data = get_proxy_by_redis(redis)
                proxy_host = proxy_data.get('proxy_address').split(":")[0]            # proxy ip
                proxy_port = proxy_data.get('proxy_address').split(":")[1]            # proxy port
                proxy_options = getProxyOptions(proxy_host,proxy_port,proxy_data.get('proxy_uname'),proxy_data.get('proxy_pass'))


        print(f"===============使用代理:{proxy_data.get('proxy_address')}")

        browser = uc_wire.Chrome(
            driver_executable_path=driver_path,
            options=options,
            seleniumwire_options=proxy_options
        )
    else:
        browser = uc_wire.Chrome(
            driver_executable_path=driver_path,
            options=options
        )
    # 设置超时时间
    if(setTimeOut):
        try:
            browser.set_page_load_timeout(10)
            browser.get(host)
        except TimeoutException:
            print("=======================init chrome host timeout=======================")
            sys.exit()
    else:
        browser.get(host)

    return browser

# 支持 tab页切换
def initSelWireChromePlus(useProxy,isHeadless,host,useTab):
    options = uc.ChromeOptions()
    options.add_argument("--disable-blink-features=AutomationControlled")
    driver_path = r'C:\Program Files\Google\Chrome\Application\chromedriver.exe'
    options.add_argument('--ignore-certificate-errors')
    options.add_argument('--ignore-ssl-errors')
    options.add_argument('--allow-insecure-localhost')
    if(useTab):
        options.add_argument('--disable-popup-blocking')
        options.add_argument('--disable-web-security')
        options.add_argument('--allow-running-insecure-content')
    if isHeadless:
        options.add_argument('--headless=new')
    if useProxy:
        proxy_data = get_proxy()
        print(f"===============使用代理:{proxy_data.get('proxy_address')}")
        proxy_host = proxy_data.get('proxy_address').split(":")[0]            # proxy ip
        proxy_port = proxy_data.get('proxy_address').split(":")[1]            # proxy port
        proxy_options = getProxyOptions(proxy_host,proxy_port,proxy_data.get('proxy_uname'),proxy_data.get('proxy_pass'))
        browser = uc_wire.Chrome(
            driver_executable_path=driver_path,
            options=options,
            seleniumwire_options=proxy_options
        )
    else:
        browser = uc_wire.Chrome(
            driver_executable_path=driver_path,
            options=options
        )

    #测试代理
    # browser.get('http://httpbin.org/ip')
    # time.sleep(3)
    browser.get(host)
    return browser

# useProxy: 是否启用代理
def initChrome(useProxy,isHeadless,host):
    ### 初始化chrome浏览器 和 cookie
    driver_path = r'C:\Program Files\Google\Chrome\Application\chromedriver.exe'
    option = ChromeOptions()
    if isHeadless:
        option.add_argument('--headless=new')
    if useProxy:
        proxy_data = get_proxy()
        print(f"===============使用代理:{proxy_data.get('proxy_address')}")
        proxy_host = proxy_data.get('proxy_address').split(":")[0]            # proxy ip
        proxy_port = proxy_data.get('proxy_address').split(":")[1]            # proxy port
        # proxy_username = "d2231274096"                      # 代理账号
        # proxy_password = "ela9v3e9"                         # 代理密码
        proxy_username = proxy_data.get('proxy_uname')
        proxy_password = proxy_data.get('proxy_pass')

        extension_path = cpae(proxy_host, proxy_port, proxy_username, proxy_password)   # 配置代理插件
        option.add_extension(extension_path)
        option.add_argument('--ignore-certificate-errors')
        option.add_argument('--disable-web-security')
        option.add_argument('--allow-running-insecure-content')
        option.add_argument('--no-sandbox')
        option.add_argument('--disable-dev-shm-usage')
        option.add_argument('--ignore-ssl-errors')

    browser = uc.Chrome(driver_executable_path=driver_path,options=option)
    browser.set_window_size(1366,768)
    # # 定义cookie 需要先通过get_cookie.py 生成cookie.txt
    # cookies = []
    # with open('./cookie/cookie.txt', 'r') as f:
    #     cookies = json.load(f)
    # # 先访问一下主页 让browser先识别域名
    # url = f"https://quote.eastmoney.com/{jys}{stockCode}.html"
    # browser.get(url)
    browser.get(host)
    # time.sleep(2)       # 让页面加载一下
    # # 加载cookie
    # for cookie in cookies:
    #     # 调整域名为当前域名 (如果域名不匹配会报错)
    #     if '.10jqka.com.cn' == cookie['domain']:
    #         # 如果cookie的域名和当前browser不匹配会报错
    #         browser.add_cookie(cookie)
    #         continue
    # # 刷新使Cookie生效
    # browser.refresh()
    return browser

def get_proxy():
    print("====get proxy====")
    # 2M 默认走2M代理
    url = "https://dps.kdlapi.com/api/getdps/?secret_id=ondbxg8msovv7ury9qbe&signature=zft63syjut8u3og5m9j5wung50mwah5f&num=1&format=text&sep=1"
    proxy_pass = 'ela9v3e9'
    proxy_uname = 'd2231274096'
    # 判断调用链的根元素 选择
    stack = inspect.stack()
    call_chain = get_call_chain(stack)
    # print(f"contains element {call_chain.__contains__('ths_gn_stocks.py')}")
    if(call_chain.__contains__('ths_stock_dfcf_kafka.py') or call_chain.__contains__('ths_gn_stocks.py') ):     # 东方财富个股任务 走4M代理
        # 4M
        print("注意:走了4M代理")
        url = "https://dps.kdlapi.com/api/getdps/?secret_id=915852818471645&signature=ri0wzjkxi1crq190qts4panru9kt5h1j&num=1&format=text&sep=1"
        proxy_pass = 'ela9v3e9'
        proxy_uname = 'd2716458517'

    proxy_address = requests.get(url)
    proxy_data = {
        "proxy_address" : proxy_address.text,
        "proxy_uname" : proxy_uname,
        "proxy_pass": proxy_pass
    }
    # return proxy_address.text
    return proxy_data

def get_proxy_by_redis(redis):
    # 2M 默认走2M代理
    url = "https://dps.kdlapi.com/api/getdps/?secret_id=ondbxg8msovv7ury9qbe&signature=zft63syjut8u3og5m9j5wung50mwah5f&num=1&format=text&sep=1"
    proxy_pass = 'ela9v3e9'
    proxy_uname = 'd2231274096'
    # 判断调用链的根元素 选择
    stack = inspect.stack()
    call_chain = get_call_chain(stack)
    # print(f"contains element {call_chain.__contains__('ths_gn_stocks.py')}")
    if(call_chain.__contains__('ths_stock_dfcf_kafka.py') ):     # 东方财富个股任务 走4M代理
        # 4M
        print("注意:走了4M代理")
        url = "https://dps.kdlapi.com/api/getdps/?secret_id=915852818471645&signature=ri0wzjkxi1crq190qts4panru9kt5h1j&num=1&format=text&sep=1"
        proxy_pass = 'ela9v3e9'
        proxy_uname = 'd2716458517'

    proxy_address = requests.get(url)
    proxy_data = {
        "proxy_address" : proxy_address.text,
        "proxy_uname" : proxy_uname,
        "proxy_pass": proxy_pass
    }
    # 将代理信息写入缓存 设置2分钟超时时间
    name = f'stock:proxy:ex:{sg.batch}'
    proxy_host = proxy_data.get('proxy_address').split(":")[0]            # proxy ip
    proxy_port = proxy_data.get('proxy_address').split(":")[1]            # proxy port
    redis.hset(name=name,key='proxy_host',value=proxy_host)
    redis.hset(name=name,key='proxy_port',value=proxy_port)
    redis.hset(name=name,key='proxy_uname',value=proxy_data.get('proxy_uname'))
    redis.hset(name=name,key='proxy_pass',value=proxy_data.get('proxy_pass'))
    redis.expire(name=name,time=180)

    return proxy_data


def get_call_chain(stack):
    """打印完整的调用链"""
    print("\n 完整调用链:")
    call_chain =set()
    for i, frame_info in enumerate(stack):
        filename = os.path.basename(frame_info.filename)
        print(f"{i}: {filename} -> {frame_info.function} (行号: {frame_info.lineno})")
        call_chain.add(filename)
    return call_chain




